package com.funsport.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.funsport.entity.Notification;
import com.funsport.entity.User;
import com.funsport.service.INotificationService;
import com.funsport.service.IUserService;
import com.funsport.util.WeChatUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.funsport.service.INotificationService;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 通知服务实现
 * 处理系统通知、消息推送等功能
 *
 * @author Fun-Sport Team
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class NotificationServiceImpl extends com.baomidou.mybatisplus.extension.service.impl.ServiceImpl<com.funsport.mapper.NotificationMapper, Notification> implements INotificationService {

    private final IUserService userService;
    private final WeChatUtil weChatUtil;

    private static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm");

    @Override
    public boolean sendEventReminder(List<Long> userIds, String eventTitle, LocalDateTime eventTime) {
        if (userIds == null || userIds.isEmpty()) {
            return false;
        }

        List<User> users = userService.listByIds(userIds);
        int successCount = 0;

        for (User user : users) {
            if (user.getOpenid() == null || user.getOpenid().isEmpty()) {
                continue;
            }

            try {
                // 构造模板消息数据
                Map<String, Object> data = new HashMap<>();
                Map<String, String> thing1 = new HashMap<>();
                thing1.put("value", eventTitle.length() > 20 ? eventTitle.substring(0, 20) : eventTitle);
                data.put("thing1", thing1);

                Map<String, String> time2 = new HashMap<>();
                time2.put("value", eventTime.format(TIME_FORMATTER));
                data.put("time2", time2);

                Map<String, String> thing3 = new HashMap<>();
                thing3.put("value", "请准时参加");
                data.put("thing3", thing3);

                // 发送模板消息
                boolean result = weChatUtil.sendTemplateMessage(
                        user.getOpenid(),
                        "ACTIVITY_REMINDER_TEMPLATE_ID",
                        data,
                        "pages/activity/detail"
                );

                if (result) {
                    successCount++;
                }

                // 同时创建应用内通知
                createInAppNotification(
                        user.getId(),
                        "活动提醒",
                        String.format("您报名的活动【%s】即将开始，时间：%s", eventTitle, eventTime.format(TIME_FORMATTER)),
                        "event_reminder",
                        null,
                        "event"
                );
            } catch (Exception e) {
                log.error("发送活动提醒失败: userId={}", user.getId(), e);
            }
        }

        log.info("发送活动提醒: 总数={}, 成功={}", users.size(), successCount);
        return successCount > 0;
    }

    @Override
    public boolean sendSignupConfirmation(Long userId, String eventTitle, LocalDateTime eventTime) {
        User user = userService.getById(userId);
        if (user == null) {
            return false;
        }

        try {
            // 发送微信模板消息
            if (user.getOpenid() != null && !user.getOpenid().isEmpty()) {
                Map<String, Object> data = new HashMap<>();
                Map<String, String> thing1 = new HashMap<>();
                thing1.put("value", eventTitle.length() > 20 ? eventTitle.substring(0, 20) : eventTitle);
                data.put("thing1", thing1);

                Map<String, String> time2 = new HashMap<>();
                time2.put("value", eventTime.format(TIME_FORMATTER));
                data.put("time2", time2);

                Map<String, String> thing3 = new HashMap<>();
                thing3.put("value", "报名成功");
                data.put("thing3", thing3);

                weChatUtil.sendTemplateMessage(
                        user.getOpenid(),
                        "SIGNUP_CONFIRMATION_TEMPLATE_ID",
                        data,
                        "pages/activity/detail"
                );
            }

            // 创建应用内通知
            createInAppNotification(
                    userId,
                    "报名成功",
                    String.format("您已成功报名活动【%s】，活动时间：%s", eventTitle, eventTime.format(TIME_FORMATTER)),
                    "signup_confirmation",
                    null,
                    "event"
            );

            log.info("发送报名确认: userId={}, eventTitle={}", userId, eventTitle);
            return true;
        } catch (Exception e) {
            log.error("发送报名确认失败: userId={}", userId, e);
            return false;
        }
    }

    @Override
    public boolean sendClubInvitation(Long userId, String clubName, String inviterName) {
        User user = userService.getById(userId);
        if (user == null) {
            return false;
        }

        try {
            // 发送微信模板消息
            if (user.getOpenid() != null && !user.getOpenid().isEmpty()) {
                Map<String, Object> data = new HashMap<>();
                Map<String, String> thing1 = new HashMap<>();
                thing1.put("value", clubName.length() > 20 ? clubName.substring(0, 20) : clubName);
                data.put("thing1", thing1);

                Map<String, String> thing2 = new HashMap<>();
                thing2.put("value", inviterName);
                data.put("thing2", thing2);

                Map<String, String> thing3 = new HashMap<>();
                thing3.put("value", "点击查看详情");
                data.put("thing3", thing3);

                weChatUtil.sendTemplateMessage(
                        user.getOpenid(),
                        "CLUB_INVITATION_TEMPLATE_ID",
                        data,
                        "pages/club/detail"
                );
            }

            // 创建应用内通知
            createInAppNotification(
                    userId,
                    "俱乐部邀请",
                    String.format("%s 邀请您加入俱乐部【%s】", inviterName, clubName),
                    "club_invitation",
                    null,
                    "club"
            );

            log.info("发送俱乐部邀请: userId={}, clubName={}", userId, clubName);
            return true;
        } catch (Exception e) {
            log.error("发送俱乐部邀请失败: userId={}", userId, e);
            return false;
        }
    }

    @Override
    public int sendSystemNotification(List<Long> userIds, String title, String content) {
        if (userIds == null || userIds.isEmpty()) {
            return 0;
        }

        List<User> users = userService.listByIds(userIds);
        int successCount = 0;

        for (User user : users) {
            try {
                // 发送微信模板消息
                if (user.getOpenid() != null && !user.getOpenid().isEmpty()) {
                    Map<String, Object> data = new HashMap<>();
                    Map<String, String> thing1 = new HashMap<>();
                    thing1.put("value", title.length() > 20 ? title.substring(0, 20) : title);
                    data.put("thing1", thing1);

                    Map<String, String> thing2 = new HashMap<>();
                    String shortContent = content.length() > 20 ? content.substring(0, 20) + "..." : content;
                    thing2.put("value", shortContent);
                    data.put("thing2", thing2);

                    weChatUtil.sendTemplateMessage(
                            user.getOpenid(),
                            "SYSTEM_NOTIFICATION_TEMPLATE_ID",
                            data,
                            null
                    );
                }

                // 创建应用内通知
                boolean result = createInAppNotification(
                        user.getId(),
                        title,
                        content,
                        "system",
                        null,
                        null
                );

                if (result) {
                    successCount++;
                }
            } catch (Exception e) {
                log.error("发送系统通知失败: userId={}", user.getId(), e);
            }
        }

        log.info("发送系统通知: 总数={}, 成功={}", users.size(), successCount);
        return successCount;
    }

    @Override
    @Transactional
    public boolean createInAppNotification(Long userId, String title, String content,
                                          String notificationType, Long relatedId, String relatedType) {
        try {
            Notification notification = new Notification();
            notification.setUserId(userId);
            notification.setTitle(title);
            notification.setContent(content);
            notification.setNotificationType(notificationType);
            notification.setRelatedId(relatedId);
            notification.setRelatedType(relatedType);
            notification.setIsRead(false);

            boolean result = save(notification);
            
            if (result) {
                log.info("创建应用内通知成功: userId={}, title={}", userId, title);
            }
            
            return result;
        } catch (Exception e) {
            log.error("创建应用内通知失败: userId={}", userId, e);
            return false;
        }
    }

    @Override
    public List<Notification> getUserNotifications(Long userId, Integer limit) {
        if (limit == null || limit <= 0) {
            limit = 20;
        }

        return list(new LambdaQueryWrapper<Notification>()
                .eq(Notification::getUserId, userId)
                .orderByDesc(Notification::getCreatedAt)
                .last("LIMIT " + limit)
        );
    }

    @Override
    @Transactional
    public boolean markAsRead(Long notificationId, Long userId) {
        Notification notification = getById(notificationId);
        
        if (notification == null || !notification.getUserId().equals(userId)) {
            return false;
        }

        notification.setIsRead(true);
        notification.setReadAt(LocalDateTime.now());
        
        return updateById(notification);
    }

    @Override
    public int getUnreadCount(Long userId) {
        return (int) count(new LambdaQueryWrapper<Notification>()
                .eq(Notification::getUserId, userId)
                .eq(Notification::getIsRead, false)
        );
    }
}
